﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Entities
{
    /// <summary>
    /// Класс пользователя системы
    /// </summary>
    public class User : BaseEntity
    {
        private string login;
        private string password;
        private List<Role> _roles;

        /// <summary>
        /// Список ролей пользователя
        /// Уровень привилегий пользователя будет определяться наименьшим уровнем привилегий его ролей
        /// </summary>
        public List<Role> Roles
        {
            get
            { return _roles; }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                _roles = value;
            }
        }

        /// <summary>
        /// Возвращает уровень привилегий пользователя
        /// read-only
        /// </summary>
        public UserPrivilegeLevels PrivilegeLevel
        {
            get
            {
                var rlist = Roles.OrderBy((item) => ((int)item.RoleLevel));
                if (rlist.Count() == 0)
                    return UserPrivilegeLevels.Guest;
                return rlist.ElementAt(0).RoleLevel;
            }
        }

        /// <summary>
        /// Имя входа в систему
        /// </summary>
        public string Login
        {
            get { return this.login; }
            set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("Login string cannot be null or empty");
                }
                this.State = EntityState.Modified;
                this.login = value;
            }
        }

        /// <summary>
        /// Хеш пароля
        /// </summary>
        public string Password
        {
            get
            {
                return password;
            }
            set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("Password string cannot be null or empty");
                }
                this.State = EntityState.Modified;
                this.password = value;
            }
        }

        private int lastQuota;
        /// <summary>
        /// Оставшееся свободное место для размещения пользовательских файлов (в Мб)
        /// </summary>
        public int LastQuota
        {
            get
            {
                return this.lastQuota;
            }
            set
            {
                if (value < 0)
                {
                    throw new ArgumentException("Last quota cannot be less than 0");
                }
                this.State = EntityState.Modified;
                this.lastQuota = value;
            }
        }

        private string email;
        /// <summary>
        /// E-Mail пользователя
        /// </summary>
        public string Email
        {
            get
            {
                return this.email;
            }
            set
            {
                if (String.IsNullOrWhiteSpace(value))
                {
                    throw new ArgumentException("Email string cannot be null or empty");
                }
                this.State = EntityState.Modified;
                this.email = value;
            }
        }

        private List<int> hostedFiles;
        /// <summary>
        /// Список загруженных пользователем файлов
        /// </summary>
        public List<int> HostedFiles
        {
            get
            {
                return this.hostedFiles;
            }
            set
            {
                if (value == null)
                {
                    throw new ArgumentNullException();
                }
                this.State = EntityState.Modified;
                this.hostedFiles = value;
            }
        }

        /// <summary>
        /// Счетчик одновременных закачек для ограничений
        /// </summary>
        public int CurrentDownloadsCount { get; private set; }

        public void IncrementCDCount()
        {
            this.CurrentDownloadsCount++;
            this.State = EntityState.Modified;
        }

        public void DecrementCDCount()
        {
            if (this.CurrentDownloadsCount > 0)
            {
                this.CurrentDownloadsCount--;
                this.State = EntityState.Modified;
            }
        }

        public bool IsNull
        {
            get
            {
                return this.ID == -1;
            }
        }

        public bool IsAuthInstance
        {
            get
            {
                return this.ID == -3;
            }
        }

        public User()
            : base()
        {
            this.CurrentDownloadsCount = 0;
        }

        public User(User src)
            : base(src.ID)
        {
            this.Login = src.Login;
            this.Password = src.Password;
            this.HostedFiles = new List<int>(src.HostedFiles);
            this.Roles = new List<Role>(src.Roles);
            this.CurrentDownloadsCount = src.CurrentDownloadsCount;
            this.Email = src.Email;
            this.LastQuota = src.LastQuota;
            this.State = src.State;
        }

        public User(string Login, string Password)
            : base(-2)
        {
            this.Login = Login;
            this.Password = Password;
        }
    }
}
